package com.ilarele.shopping.client.util;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;

import android.app.Activity;

import com.ilarele.shopping.Message;
import com.ilarele.shopping.Product;
import com.ilarele.shopping.ProductComment;
import com.ilarele.shopping.ProductInfo;
import com.ilarele.shopping.ProductName;
import com.ilarele.shopping.ProductPicture;
import com.ilarele.shopping.ProductTag;

public class Communication {
	public static Message sendMessage(Message sm, boolean waitResp) {
		Socket socket = null;
		ObjectOutputStream oos = null;
		ObjectInputStream ois = null;
		Message mess = null;
		try {
			socket = new Socket(Global.SERVER_IP, Global.PORT);
			oos = new ObjectOutputStream(socket.getOutputStream());
			ois = new ObjectInputStream(socket.getInputStream());
			oos.writeObject(sm);
			if (waitResp) {
				mess = (Message) ois.readObject();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ois != null)
				try {
					ois.close();
					if (oos != null)
						oos.close();
					if (socket != null)
						socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		return mess;
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<Product> sendFilteredMessage() {
		Message msg = new Message();
		msg.idClient = Global.clientId;
		msg.type = Message.TYPE_CLIENT_FILTER_PRODS;
		Message response = sendMessage(msg, true);
		return (ArrayList<Product>) response.content;
	}

	public static void sendRatePictureMessage(ProductPicture pPicture) {
		if (pPicture.dbRate != 0) {
			Message msg = new Message();
			msg.idClient = Global.clientId;
			msg.type = Message.TYPE_CLIENT_RATE_PICTURE;
			msg.content = pPicture;
			sendMessage(msg, false);
		}
	}

	public static void sendRateNameMessage(ProductName pName) {
		if (pName.dbRate != 0) {
			Message msg = new Message();
			msg.idClient = Global.clientId;
			msg.type = Message.TYPE_CLIENT_RATE_NAME;
			msg.content = pName;
			sendMessage(msg, false);
		}
	}

	private static void sendRateInfoMessage(ProductInfo pInfo) {
		if (pInfo.dbRate != 0) {
			Message msg = new Message();
			msg.idClient = Global.clientId;
			msg.type = Message.TYPE_CLIENT_RATE_INFO;
			msg.content = pInfo;
			sendMessage(msg, false);
		}
	}

	private static void sendRateTagsMessage(ProductTag pTags) {
		if (pTags.dbRate != 0) {
			Message msg = new Message();
			msg.idClient = Global.clientId;
			msg.type = Message.TYPE_CLIENT_RATE_TAGS;
			msg.content = pTags;
			sendMessage(msg, false);
		}
	}

	public static void sendRateMessage(Activity activity, Product product) {
		if (product.pPicture.dbRate != product.pPicture.unsavedRate) {
			product.pPicture.dbRate = product.pPicture.unsavedRate;
			DBUtil.updatePictureRate(activity, product);
			sendRatePictureMessage(product.pPicture);
		}

		if (product.pName.dbRate != product.pName.unsavedRate) {
			product.pName.dbRate = product.pName.unsavedRate;
			DBUtil.updateNameRate(activity, product);
			sendRateNameMessage(product.pName);
		}

		if (product.pInfo.dbRate != product.pInfo.unsavedRate) {
			product.pInfo.dbRate = product.pInfo.unsavedRate;
			DBUtil.updateInfoRate(activity, product);
			sendRateInfoMessage(product.pInfo);
		}
		if (product.pTags.dbRate != product.pTags.unsavedRate) {
			product.pTags.dbRate = product.pTags.unsavedRate;
			DBUtil.updateTagsRate(activity, product);
			sendRateTagsMessage(product.pTags);
		}
	}

	public static boolean getNextRatedPicture(int dir, Product product) {
		Message sm = new Message();
		if (dir > 0)
			sm.type = Message.TYPE_CLIENT_NEXT_RATE_PICTURE;
		else
			sm.type = Message.TYPE_CLIENT_PREV_RATE_PICTURE;
		sm.idClient = Global.clientId;
		sm.content = product;
		Message msg = sendMessage(sm, true);
		if (msg.content != null) {
			Product newProd = ((Product) msg.content);
			product.pPicture.imageUrl = newProd.pPicture.imageUrl;
			product.pPicture.id = newProd.pPicture.id;
			return true;
		}
		return false;
	}

	public static boolean getNextRatedName(int dir, Product product) {
		Message sm = new Message();
		if (dir > 0)
			sm.type = Message.TYPE_CLIENT_NEXT_RATE_NAME;
		else
			sm.type = Message.TYPE_CLIENT_PREV_RATE_NAME;
		sm.idClient = Global.clientId;
		sm.content = product;
		Message msg = sendMessage(sm, true);
		if (msg.content != null) {
			Product newProd = ((Product) msg.content);
			product.pName.name = newProd.pName.name;
			product.pName.id = newProd.pName.id;
			return true;
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<ProductComment> getComments(String prodId) {
		Message sm = new Message();
		sm.type = Message.TYPE_CLIENT_GET_COMMENTS;
		sm.idClient = Global.clientId;
		sm.content = prodId;
		Message msg = sendMessage(sm, true);
		return (ArrayList<ProductComment>) msg.content;
	}

	public static void sendComment(Product mDialogProd) {
		Message msg = new Message();
		msg.type = Message.TYPE_CLIENT_POST_COMMENT;
		msg.idClient = Global.clientId;
		msg.content = mDialogProd;
		System.out.println("send prodId " + mDialogProd.idProd);
		sendMessage(msg, false);
	}

	public static boolean getNextRatedInfo(int dir, Product product) {
		Message sm = new Message();
		if (dir > 0)
			sm.type = Message.TYPE_CLIENT_NEXT_RATE_INFO;
		else
			sm.type = Message.TYPE_CLIENT_PREV_RATE_INFO;
		sm.idClient = Global.clientId;
		sm.content = product;
		Message msg = sendMessage(sm, true);
		if (msg.content != null) {
			Product newProd = ((Product) msg.content);
			product.pInfo.rating = newProd.pInfo.rating;
			product.pInfo.price = newProd.pInfo.price;
			product.pInfo.pLocation = newProd.pInfo.pLocation;
			product.pInfo.id = newProd.pInfo.id;
			return true;
		}
		return false;
	}

	public static boolean getNextRatedTags(int dir, Product product) {
		Message sm = new Message();
		if (dir > 0)
			sm.type = Message.TYPE_CLIENT_NEXT_RATE_TAGS;
		else
			sm.type = Message.TYPE_CLIENT_PREV_RATE_TAGS;
		sm.idClient = Global.clientId;
		sm.content = product;
		Message msg = sendMessage(sm, true);
		if (msg.content != null) {
			Product newProd = ((Product) msg.content);
			product.pTags.tags = newProd.pTags.tags;
			product.pTags.id = newProd.pTags.id;
			return true;
		}
		return false;
	}

	public static String uploadPicture(String filePath) {
		if (filePath == null)
			return null;
		Socket socket = null;
		DataOutputStream dos = null;
		FileInputStream file = null;
		ObjectInputStream ios = null;
		ObjectOutputStream oos = null;
		String result = null;
		try {
			socket = new Socket(Global.SERVER_IMAGE_IP, Global.IMAGE_SEND_PORT);

			// send name
			oos = new ObjectOutputStream(socket.getOutputStream());
			oos.writeObject(filePath);
			System.out.println("uploaded pic named " + filePath);
			// send pic
			file = new FileInputStream(new File(
					Global.SHOPPING_PICTURES_DIRECTORY, filePath));
			dos = new DataOutputStream(socket.getOutputStream());
			int i;
			while ((i = file.read()) > -1)
				dos.write(i);
			ios = new ObjectInputStream(socket.getInputStream());
			result = (String) ios.readObject();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (dos != null)
				try {
					dos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			if (socket != null)
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			if (file != null)
				try {
					file.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			if (ios != null)
				try {
					ios.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		System.out.println("new path = " + result);
		return result;
	}

	public static void sendPrivacy(boolean isChecked) {
		Message sm = new Message();
		sm.type = Message.TYPE_PRIVACY;
		sm.idClient = Global.clientId;
		sm.content = isChecked;
		sendMessage(sm, false);
	}
}
